package com.lcc.lynx.jdbc.ec;

import com.lcc.lynx.common.exception.e.JDBCException;
import com.lcc.lynx.common.utils.LambdaUtils;
import com.lcc.lynx.common.utils.ReflectUtil;
import com.lcc.lynx.common.utils.SSupplier;
import com.lcc.lynx.common.utils.StrUtil;
import com.lcc.lynx.jdbc.enums.Operator;
import com.lcc.lynx.jdbc.pojo.TablePojo;
import com.lcc.lynx.jdbc.util.JDBCUtil;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.util.List;

/**
 * 增强条件
 *
 * @author lcc
 * @date 2025/7/14 17:08
 */
public class EnhanceCondition {

    private static final String EC_KEY = "enhanceConditions";

    // 字段名
    private SSupplier getFun;
    private SerializedLambda lambda;
    private String columnName;

    private TablePojo tablePojo;

    private boolean isDate;

    public EnhanceCondition() {
    }

    public EnhanceCondition(TablePojo tablePojo) {
        this.tablePojo = tablePojo;
    }

    public EnhanceCondition(SSupplier getFun, TablePojo tablePojo) {
        this.tablePojo = tablePojo;
        and(getFun);
    }

    public EnhanceCondition and(SSupplier getFun) {
        this.getFun = getFun;
        this.lambda = LambdaUtils.doGetLambda(getFun);
        this.isDate = lambda.getImplMethodSignature().contains("java/util/Date");
        return this;
    }

    public EnhanceCondition column(String columnName) {
        this.columnName = columnName;
        return this;
    }

    public EnhanceCondition and(SSupplier getFun, String columnName) {
        this.columnName = columnName;
        return and(getFun);
    }

    private EnhanceCondition putEnhanceCondition(Operator operator, Object... args) {

        if(getFun == null){
            throw new JDBCException("未传入对应字段的get方法");
        }
        if (operator.isDate() && !(args[0] instanceof String s && s.length() == 10 && s.matches("\\d{4}-\\d{2}-\\d{2}"))) {
            throw new JDBCException("日期参数格式错误,只支持String(yyyy-MM-dd)");
        }

        String fieldName = LambdaUtils.convertMethodToField(lambda.getImplMethodName());
        // 如果传入参数值为null, 则从对象中获取值, 并设置为null
        if (args.length == 1 && args[0] == null && (args[0] = getFun.get()) != null) {
            ReflectUtil.setObjValue(tablePojo, fieldName, null);
        }
        if (operator.hasArg() && StrUtil.isAllEmpty(args)) {
            clear();
            return this;
        }
        if(this.columnName == null){
            columnName = JDBCUtil.toLine(fieldName);
        }
        for (int i = 0; i < args.length; i++) {
            tablePojo.getTp().put(fieldName + "__" + operator.name() + "__value" + i, args[i]);
        }
        if (!tablePojo.getTp().containsKey(EC_KEY)) {
            tablePojo.getTp().put(EC_KEY, new StringBuilder());
        }

        String str = operator == Operator.NOT_EQUAL && args.length == 1 && args[0] instanceof String
                ? " and coalesce(main." + columnName + ", '') "
                : " and main." + columnName + " ";
        if (operator == Operator.IN || operator == Operator.NOT_IN) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < args.length; i++) {
                if (i > 0) sb.append(",");
                sb.append("#{tp.").append(fieldName).append("__").append(operator.name()).append("__value").append(i).append("}");
            }
            str += operator.value().replace("?", sb.toString());
        } else if (operator.hasArg()) {
            str += operator.value().replace("?", "tp." + fieldName + "__" + operator.name() + "__value");
        } else {
            str += operator.value();
        }
        ((StringBuilder) tablePojo.getTp().get(EC_KEY)).append(str);

        clear();
        return this;
    }

    private void clear() {
        this.getFun = null;
        this.lambda = null;
        this.columnName = null;
    }

    public EnhanceCondition eq(Serializable value) {
        return putEnhanceCondition(Operator.EQUAL, value);
    }

    /**
     * 不等于 !=
     */
    public EnhanceCondition ne(Serializable value) {
        return putEnhanceCondition(Operator.NOT_EQUAL, value);
    }

    /**
     * 大于 >
     */
    public EnhanceCondition gt(Serializable value) {
        return putEnhanceCondition(isDate ? Operator.DATE_GREATER_THAN : Operator.GREATER_THAN, value);
    }

    /**
     * 大于等于 >=
     */
    public EnhanceCondition ge(Serializable value) {
        return putEnhanceCondition(isDate ? Operator.DATE_GREATER_THAN_OR_EQUAL : Operator.GREATER_THAN_OR_EQUAL, value);
    }

    /**
     * 小于 <
     */
    public EnhanceCondition lt(Serializable value) {
        return putEnhanceCondition(isDate ? Operator.DATE_LESS_THAN : Operator.LESS_THAN, value);
    }

    /**
     * 小于等于 <=
     */
    public EnhanceCondition le(Serializable value) {
        return putEnhanceCondition(isDate ? Operator.DATE_LESS_THAN_OR_EQUAL : Operator.LESS_THAN_OR_EQUAL, value);
    }

    /**
     * 全模糊查询 like %?%
     */
    public EnhanceCondition like(Serializable value) {
        return putEnhanceCondition(Operator.LIKE, value);
    }

    /**
     * 非全模糊查询 not like %?%
     */
    public EnhanceCondition nLike(Serializable value) {
        return putEnhanceCondition(Operator.NOT_LIKE, value);
    }

    /**
     * 左模糊查询
     */
    public EnhanceCondition likeL(Serializable value) {
        return putEnhanceCondition(Operator.LIKE_LEFT, value);
    }

    /**
     * 非左模糊查询
     */
    public EnhanceCondition nLikeL(Serializable value) {
        return putEnhanceCondition(Operator.NOT_LIKE_LEFT, value);
    }

    /**
     * 右模糊查询
     */
    public EnhanceCondition likeR(Serializable value) {
        return putEnhanceCondition(Operator.LIKE_RIGHT, value);
    }

    /**
     * 非左模糊查询
     */
    public EnhanceCondition nLikeR(Serializable value) {
        return putEnhanceCondition(Operator.NOT_LIKE_RIGHT, value);
    }

    /**
     * 范围[?, ?]*
     */
    public EnhanceCondition between(Serializable value1, Serializable value2) {
        return putEnhanceCondition(isDate ? Operator.DATE_BETWEEN : Operator.BETWEEN, value1, value2);
    }

    /**
     * 不在范围
     */
    public EnhanceCondition nBetween(Serializable value1, Serializable value2) {
        return putEnhanceCondition(isDate ? Operator.DATE_NOT_BETWEEN : Operator.NOT_BETWEEN, value1, value2);
    }

    /**
     * 集合
     */
    public EnhanceCondition in(Serializable... values) {
        return putEnhanceCondition(Operator.IN, values);
    }

    /**
     * 不在集合
     */
    public EnhanceCondition notIn(Serializable... values) {
        return putEnhanceCondition(Operator.NOT_IN, values);
    }

    /**
     * 集合
     */
    public EnhanceCondition in(List list) {
        return putEnhanceCondition(Operator.IN, list.toArray());
    }

    /**
     * 不在集合
     */
    public EnhanceCondition notIn(List list) {
        return putEnhanceCondition(Operator.NOT_IN, list.toArray());
    }

    /**
     * 为null
     */
    public EnhanceCondition isNull() {
        return putEnhanceCondition(Operator.IS_NULL);
    }

    /**
     * 不为null
     */
    public EnhanceCondition isNotNull() {
        return putEnhanceCondition(Operator.IS_NOT_NULL);
    }


    /**
     * 等于 =
     */
    public EnhanceCondition eq(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.EQUAL, (Object) null);
    }

    /**
     * 不等于 !=
     */
    public EnhanceCondition ne(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.NOT_EQUAL, (Object) null);
    }

    /**
     * 大于 >
     */
    public EnhanceCondition gt(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(isDate ? Operator.DATE_GREATER_THAN : Operator.GREATER_THAN, (Object) null);
    }

    /**
     * 大于等于 >=
     */
    public EnhanceCondition ge(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(isDate ? Operator.DATE_GREATER_THAN_OR_EQUAL : Operator.GREATER_THAN_OR_EQUAL, (Object) null);
    }

    /**
     * 小于 <
     */
    public EnhanceCondition lt(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(isDate ? Operator.DATE_LESS_THAN : Operator.LESS_THAN, (Object) null);
    }

    /**
     * 小于等于 <=
     */
    public EnhanceCondition le(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(isDate ? Operator.DATE_LESS_THAN_OR_EQUAL : Operator.LESS_THAN_OR_EQUAL, (Object) null);
    }

    /**
     * 全模糊查询 like %?%
     */
    public EnhanceCondition like(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.LIKE, (Object) null);
    }

    /**
     * 非全模糊查询 not like %?%
     */
    public EnhanceCondition nLike(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.NOT_LIKE, (Object) null);
    }

    /**
     * 左模糊查询
     */
    public EnhanceCondition likeL(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.LIKE_LEFT, (Object) null);
    }

    /**
     * 非左模糊查询
     */
    public EnhanceCondition nLikeL(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.NOT_LIKE_LEFT, (Object) null);
    }

    /**
     * 右模糊查询
     */
    public EnhanceCondition likeR(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.LIKE_RIGHT, (Object) null);
    }

    /**
     * 非左模糊查询
     */
    public EnhanceCondition nLikeR(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.NOT_LIKE_RIGHT, (Object) null);
    }

    /**
     * 为null
     */
    public EnhanceCondition isNull(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.IS_NULL);
    }

    /**
     * 不为null
     */
    public EnhanceCondition isNotNull(SSupplier getFun) {
        return and(getFun).putEnhanceCondition(Operator.IS_NOT_NULL);
    }
}
